package it.uniba.di.mas.jpnde.behaviour;

import it.uniba.di.mas.jpnde.data.PN;
import it.uniba.di.mas.jpnde.data.Transaction;
import jade.content.onto.basic.Action;
import jade.core.ContainerID;
import jade.core.behaviours.Behaviour;
import jade.domain.FIPANames;
import jade.domain.JADEAgentManagement.CreateAgent;
import jade.domain.JADEAgentManagement.JADEManagementOntology;
import jade.lang.acl.ACLMessage;
import jade.util.leap.List;

public class PNManagerBehaviour extends Behaviour{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	private final static short AWAIT_PN=0;
	private final static short DELIVERY_PN=1;
	private final static short EXECUTE_PN=2;
	private final static short END_PN=3;
	private final static short ERROR=4;
	
	private int state=AWAIT_PN;
	
	private PN pn=null;
	
	@Override
	public void action() {
		// TODO Auto-generated method stub
		switch(state){
		case AWAIT_PN:
			receivePN();
			break;
		case DELIVERY_PN:
			delivery();
			break;
		case EXECUTE_PN:
			execute();
			break;
		}	
	}

	@Override
	public boolean done() {
		// TODO Auto-generated method stub
		return (state==ERROR)||(state==END_PN);
	}

	private void receivePN(){
		System.out.println(">>> receivePN ");
		ACLMessage message=myAgent.receive();
		try
			{
			if (message!=null)
				{
				ACLMessage reply=message.createReply();
				if ((message.getPerformative()!=ACLMessage.REQUEST)||
				    !(message.getContentObject() instanceof PN))
					{
						state=ERROR;
						reply.setPerformative(ACLMessage.FAILURE);
					}	
				else
					{
						pn=(PN)message.getContentObject();
						state=DELIVERY_PN;
						reply.setPerformative(ACLMessage.INFORM);
					}
				myAgent.send(reply);
				}
			else
				block();
			}
		catch(Exception e)
			{e.printStackTrace();}
	
	}
	
	private void delivery(){
		System.out.println(">>> delivery "+pn.getId());
		List transactions=pn.getTransactions();
		for(int i=0;i<transactions.size();i++)
			{
			Transaction t=(Transaction)transactions.get(i);
			
			CreateAgent ca=new CreateAgent();
			ca.setAgentName(t.getId()+"_"+pn.getId());
			ca.setClassName("it.uniba.di.mas.jpnde.agent.PNTransaction");
			
			try
			{
			if (!pn.getContainer().equals(""))
				ca.setContainer(new ContainerID(pn.getContainer(),null));
			else
				ca.setContainer(new ContainerID(myAgent.getContainerController().getContainerName(),null));
			
			Action act=new Action(myAgent.getAMS(),ca);
			ACLMessage request=new ACLMessage(ACLMessage.REQUEST);
			request.addReceiver(myAgent.getAMS());
			request.setOntology(JADEManagementOntology.getInstance().getName());
			request.setLanguage(FIPANames.ContentLanguage.FIPA_SL);
			request.setProtocol(FIPANames.InteractionProtocol.FIPA_REQUEST);
		
			myAgent.getContentManager().fillContent(request, act);
			myAgent.send(request);
			
			}
			catch (Exception e){
				e.printStackTrace();
			}
		}
		state=EXECUTE_PN;
	}
	
	private void execute(){
		System.out.println(">>> execute "+pn.getId());
		state=END_PN;
	}
	
	public int onEnd() {
		System.out.println(">>> onEnd "+pn.getId());
		int ret=super.onEnd();
		myAgent.doDelete();
		return ret;
	}
}
